﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Xml;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CObject;
using CDefineGlobal;
using System.Threading;
using BUS_LAYER;

namespace MySuperTank
{
    public partial class MainForm : Form
    {
        //ảnh tạm dùng để lưu lại map
        Bitmap bitmapTemp;
        Graphics gTemp;

        //mảng lưu trữ tile và tank
        List<AbstractTile> arrTile = new List<AbstractTile>();    //khởi tạo trong hàm loadmap
        List<AbstractTank> arrTank = new List<AbstractTank>();    //khởi tạo trong hàm loadform
        //List<CTank> arrComTank = new List<CTank>(); //mảng các xe tăng computer

        //các biến cục bộ khác
        //biến lưu vị trí gạch bị bắn (để xóa khỏi map)
        List<int> iRow = new List<int>(); //một viên đạn có thể phá vỡ 2 mảnh gạch 20*20
        List<int> iCol = new List<int>();
        //CChiHuy gChiHuy = new CChiHuy(); //trung tâm chỉ huy, bị bắn trúng là thua

        CMap gCurMap;   //map hiện tại mà người chơi đang chơi
        bool bDrawMap = false;  //thông báo là đã vẽ map rồi hay chưa để khỏi vẽ đi vẽ lại nhiều lần (trong sự kiện paint)
        CPlaySound gSound = new CPlaySound();     //biến âm thanh của game

        int iScore = 0; //điểm số của người chơi

        public MainForm()
        {
            InitializeComponent();
        }//end func

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //base.OnPaintBackground(e);
        }
        
        private void MainForm_Load(object sender, EventArgs e)
        {
            //Xác định thư mục Plugin
            string ThuMuc_Plugin = Application.StartupPath + @"\Plugins\Map\";
            //lấy danh sách map theo đường dẫn file dll
            QuanLy.Lay_Map(ThuMuc_Plugin);
            //khởi tạo map 
            gCurMap = QuanLy.DsMap[Program.iCurMap];
            
            //khởi tạo arrTank
            arrTank.Add(new MyTank());

            //khởi tạo các label, lb_Tank được khởi tạo ở hàm LoadMap
            lb_scores.Text = "0";
            lb_Tank.Text = gCurMap.IMap.ArrComTank.Count.ToString();
            lb_You.Text = arrTank[0].I_Life.ToString();

            //khởi tạo âm thanh
            gSound.OpenMediaFile("fire.WAV");
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            //load map chỉ một lần đầu tiên
            if (bDrawMap == false)
            {
                //khởi tạo bitmapTemp
                bitmapTemp = new Bitmap(this.Width, this.Height);
                gTemp = Graphics.FromImage(bitmapTemp);

                BUS_Map.DrawMap(gCurMap, arrTile, gTemp, bitmapTemp);
                bDrawMap = true;
            }

            //vẽ lại map khi có thay đổi
            BUS_Map.UpdateMap(gTemp);
            g.DrawImage(bitmapTemp, 0, 0);

            //vẽ danh sách computer tank
            int nCount = (CDefine.TANK_APPEAR_COUNT <= gCurMap.IMap.ArrComTank.Count) ? CDefine.TANK_APPEAR_COUNT : gCurMap.IMap.ArrComTank.Count;
            for (int i = 0; i < nCount; i++)
            {
                int iNewX = gCurMap.IMap.ArrComTank[i].Location.X;
                int iNewY = gCurMap.IMap.ArrComTank[i].Location.Y;
                g.DrawImage(gCurMap.IMap.ArrComTank[i].BCurrentBitmap, iNewX, iNewY);

                if (gCurMap.IMap.ArrComTank[i].Rocket.Enabled == true)
                    g.DrawImage(gCurMap.IMap.ArrComTank[i].Rocket.BBitmap, gCurMap.IMap.ArrComTank[i].Rocket.Location.X, gCurMap.IMap.ArrComTank[i].Rocket.Location.Y);
            }

            //vẽ player tank
            g.DrawImage(arrTank[0].BCurrentBitmap, arrTank[0].Location);

            //Vẽ đạn bay
            if (arrTank[0].Rocket.Enabled == true)
                g.DrawImage(arrTank[0].Rocket.BBitmap, arrTank[0].Rocket.Location.X, arrTank[0].Rocket.Location.Y);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //di chuyển ngẫu nhiên computer tank
            //threadRandomMoveTank.Start();
            BUS_Tank.MoveRandomComTank(gCurMap);
           
            try
            {
                //kiểm tra tương tác giữa tank với tank
                int nCount = (CDefine.TANK_APPEAR_COUNT <= gCurMap.IMap.ArrComTank.Count) ? CDefine.TANK_APPEAR_COUNT : gCurMap.IMap.ArrComTank.Count;
                //for (int i = 0 ; i < nCount -1 ; i++)
                //    for (int j = i+1; j < nCount; j++)
                //        if (QuanLy.DsMap[0].IMap.ArrComTank[i].GetRect().IntersectsWith(QuanLy.DsMap[0].IMap.ArrComTank[j].GetRect()))
                //        {
                //            QuanLy.DsMap[0].IMap.ArrComTank[i].MoveToDirection(CDefine.DIRECTION_NONE);
                //            QuanLy.DsMap[0].IMap.ArrComTank[j].MoveToDirection(CDefine.DIRECTION_NONE);
                //        }

                //kiểm tra tương tác giữa đạn với tile, nếu thiếu đoạn code này, đạn sẽ ko bay -> code bưởi quá :(
                if (arrTank[0].Rocket.Enabled == true)
                    BUS_Rocket.CheckCollisions(arrTank[0].Rocket, gCurMap);

                for (int i = 0; i < nCount; i++)
                    if (gCurMap.IMap.ArrComTank[i].Rocket.Enabled == true)
                        BUS_Rocket.CheckCollisions(gCurMap.IMap.ArrComTank[i].Rocket, gCurMap);


                //kiểm tra tương tác giữa đạn với tank, đạn với đạn
                for (int i = 0; i < nCount; i++)
                {
                    if (gCurMap.IMap.ArrComTank[i].Rocket.Enabled == true)
                    {
                        //kiểm tra tương tác đạn với đạn
                        if (arrTank[0].Rocket.GetRect().IntersectsWith(gCurMap.IMap.ArrComTank[i].Rocket.GetRect()))
                        {
                            //đạn biến mất
                            arrTank[0].Rocket.Enabled = false;
                            gCurMap.IMap.ArrComTank[i].Rocket.Enabled = false;
                        }

                        //kiểm tra người chơi bị bắn
                        if (arrTank[0].GetRect().IntersectsWith(gCurMap.IMap.ArrComTank[i].Rocket.GetRect()))
                        {
                            gCurMap.IMap.ArrComTank[i].Rocket.Enabled = false;
                            arrTank[0].IncreaseLife(-1);
                            lb_You.Text = arrTank[0].I_Life.ToString();
                        }
                    }

                    //kiểm tra người chơi bắn trúng địch
                    if (arrTank[0].Rocket.Enabled == true)
                        if (arrTank[0].Rocket.GetRect().IntersectsWith(gCurMap.IMap.ArrComTank[i].GetRect()))
                        {
                            arrTank[0].Rocket.Enabled = false;
                            gCurMap.IMap.ArrComTank.RemoveAt(i);
                            lb_Tank.Text = gCurMap.IMap.ArrComTank.Count.ToString();
                            i--;
                        }
                }

                //kiểm tra thắng game
                CheckWinGame();

                //kiểm tra game over
                CheckGameOver(gCurMap);
            }
            catch (Exception)
            { }

            Invalidate();
        }

        private void CheckWinGame()
        {
            if (gCurMap.IMap.ArrComTank.Count <= 0)
            {
                //qua màn
                Program.iCurMap++;
                gCurMap = QuanLy.DsMap[Program.iCurMap];

                //đặt lại vị trí xuất hiện của người chơi
                arrTank[0].ChangeLocation(160, 480);

                //thông báo cần vẽ lại map
                bDrawMap = false;
            }
        }

        private void CheckGameOver(CMap map)
        {
            //người chơi hết life
            if (arrTank[0].I_Life < 0)
                GameOver();

            //chỉ huy bị bắn trúng
            //đúng ra là "240, 480, 40, 40" nhưng vì một chút sai sót chưa sửa được nên phải để kích thước này :(
            Rectangle r = new Rectangle(220, 480, 60, 40);  //40 là kích thước của chỉ huy
            
            //kiểm tra chỉ huy bị người chơi bắn
            if (arrTank[0].Rocket.Enabled == true)
                if (arrTank[0].Rocket.GetRect().IntersectsWith(r))
                {
                    arrTank[0].Rocket.Enabled = false;
                    BUS_Map.ChiHuy.Die();   //thay ảnh cho chỉ huy
                    GameOver();
                }

            //kiểm tra chỉ huy bị tank địch bắn
            int nCount = (CDefine.TANK_APPEAR_COUNT <= map.IMap.ArrComTank.Count) ? CDefine.TANK_APPEAR_COUNT : map.IMap.ArrComTank.Count;
            for (int i = 0; i < nCount; i++)
            {
                if (map.IMap.ArrComTank[i].Rocket.Enabled == true)
                    if (map.IMap.ArrComTank[i].Rocket.GetRect().IntersectsWith(r))
                    {
                        map.IMap.ArrComTank[i].Rocket.Enabled = false;
                        BUS_Map.ChiHuy.Die();   //thay ảnh cho chỉ huy
                        GameOver();
                    }
            }
        }

        private void GameOver()
        {
            if (Program.isGameOver == false)
            {
                Program.isGameOver = true;
                MessageBox.Show("Game Over");
                this.Close();
            }
        }

        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Left: //di chuyển trái
                    arrTank[0].I_Direction = CDefine.DIRECTION_LEFT;
                    arrTank[0].MoveToDirection(CDefine.DIRECTION_LEFT);
                    BUS_Tank.CheckCollisions(arrTank[0], gCurMap);
                    break;

                case Keys.Right:   //di chuyển phải
                    //chuyển thuộc tính I_Direction để xe có thể quay sang phải
                    arrTank[0].I_Direction = CDefine.DIRECTION_RIGHT;
                    //chuyển thuộc tính I_ToMove để ra lệnh cho xe chạy sang phải
                    arrTank[0].MoveToDirection(CDefine.DIRECTION_RIGHT);
                    BUS_Tank.CheckCollisions(arrTank[0], gCurMap);
                    break;

                case Keys.Up:      //di chuyển lên
                    arrTank[0].I_Direction = CDefine.DIRECTION_UP;
                    arrTank[0].MoveToDirection(CDefine.DIRECTION_UP);
                    BUS_Tank.CheckCollisions(arrTank[0], gCurMap);
                    break;

                case Keys.Down:    //di chuyển xuống
                    arrTank[0].I_Direction = CDefine.DIRECTION_DOWN;
                    arrTank[0].MoveToDirection(CDefine.DIRECTION_DOWN);
                    BUS_Tank.CheckCollisions(arrTank[0], gCurMap);
                    break;

                case Keys.ControlKey: //bắn

                    gSound.PlayMediaFile(false);

                    if (arrTank[0].Rocket.Enabled == false)
                    {
                        //âm thanh tí nào :)
                        //gSound.ClosePlayer();

                        arrTank[0].Fire();
                    }
                    break;
            }
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            bitmapTemp.Dispose();
            gTemp.Dispose();

            Program.isMainFormOpen = false;
            Application.Exit();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            XmlDocument save = new XmlDocument();
            save.Load("Save.xml");
            XmlElement node = save.DocumentElement;
            XmlElement map = (XmlElement)node.SelectSingleNode("map");
            map.InnerText = Program.iCurMap.ToString();

            save.Save("Save.xml");
            MessageBox.Show("Đã lưu");
        }

    }//end class
}//end namespace
